#pragma once

#include <iostream>
#include <memory>
#include <wait.h>
#include "Socket.hpp"
#include <fcntl.h>
#include <functional>

namespace TcpServerModule
{
    using namespace SocketModule;
    using namespace LogModule;
    using tcphandler_t = std::function<bool(SockPtr, InetAddr)>;
    
    // 只负责IO，不对协议进行处理
    class TcpServer
    {
    public:
        TcpServer(const uint16_t port)
            : _ListenSocket(std::make_unique<TcpSocket>()), _running(0),_port(port)
        {
           
        }
        void InitHandler(tcphandler_t handler)
        {
            _handler = handler;
            _ListenSocket->BuildTcpSocket(_port);
        }
        void Loop()
        {
            _running = true;
            while (_running)
            {
                // Accept
                InetAddr client_addr;
                auto sockfd = _ListenSocket->Accept(&client_addr);
                LOG(LogLevel::ERROR) << "_SOCKFD" << sockfd;
                if (sockfd == nullptr)
                    continue;
                // IO处理
                LOG(LogLevel::INFO) << "get client info:" << client_addr.Addr();
                pid_t pid = fork();
                if (pid == 0)
                {
                    // 关闭不需要的下标
                    _ListenSocket->Close();
                    if (fork() > 0)
                        exit(0);
                    
                    _handler(sockfd, client_addr);
                    exit(0);
                }
               // sockfd->Close();
            }
            _running = false;
        }
        ~TcpServer()
        {
            _ListenSocket->Close();
        }

    private:
        std::unique_ptr<Socket> _ListenSocket;
        bool _running;
        tcphandler_t _handler;
        int _port;
    };

}
